/* 事件停止被触发N秒后才会再次触发回调
 * @param {Function} func - 回调执行函数
 * @param {String} wait - 触发间隔
 * @param {Boolean} immediate - 是否延时执行
 */
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

/* 轮询条件函数，根据状态执行相应回调
 * @param {Function} fn- 条件函数
 * @param {Function} callback - 成功回调
 * @param {Function} errback - 失败回调
 * @param {int} timeout - 超时间隔
 * @param {int} interval - 轮询间隔
 */
function poll(fn, callback, errback, timeout, interval) {
    var endTime = Number(new Date()) + (timeout || 2000);
    interval = interval || 100;

    (function p() {
            // If the condition is met, we're done! 
            if(fn()) {
                callback();
            }
            // If the condition isn't met but the timeout hasn't elapsed, go again
            else if (Number(new Date()) < endTime) {
                setTimeout(p, interval);
            }
            // Didn't match and too much time, reject!
            else {
                errback(new Error('timed out for ' + fn + ': ' + arguments));
            }
    })();
}

/**
 * 一次执行函数
 */
function once(fn, context) { 
    var result;

    return function() { 
        if(fn) {
            result = fn.apply(context || this, arguments);
            fn = null;
        }

        return result;
    };
}
/**
 * 从字符串输入中得到绝对路径
 */
var getAbsoluteUrl = (function() {
    var a;

    return function(url) {
        if(!a) a = document.createElement('a');
        a.href = url;

        return a.href;
    };
})();

/**
 * 使用css选择器来选取节点修改样式不太高效，可以选择用js新建一段css样式规则插入。
 */
var sheet = function() {
    var style = document.createElement('style');

    // WebKit 兼容
    style.appendChild(document.createTextNode(''));

    document.head.appendChild(style);
    return style.sheet;
}

/**
 * 判断页面内的元素是否具有某些属性值。
 */
function matchesSelector(el, selector) {
    var p = Element.prototype;
    var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) {
        return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
    };
    return f.call(el, selector);
}
// Usage
// matchesSelector(document.getElementById('myDiv'), 'div.someSelector[some-attribute=true]')

/*
* 参数说明：
* number：要格式化的数字
* decimals：保留几位小数
* dec_point：小数点符号
* thousands_sep：千分位符号
* roundtag:舍入参数，默认 "ceil" 向上取,"floor"向下取,"round" 四舍五入
* */
function number_format(number, decimals, dec_point, thousands_sep, roundtag) {
 if (+number < 0.01) {
   return '0.00';
 }
 decimals = decimals || 2;
  number = (number + '').replace(/[^0-9+-Ee.]/g, '');
  roundtag = roundtag || "round"; //"ceil","floor","round"
  var n = !isFinite(+number) ? 0 : +number,
    prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
    sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
    dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
    s = '',
    toFixedFix = function (n, prec) {

      var k = Math.pow(10, prec);

      return '' + parseFloat(Math[roundtag](parseFloat((n * k).toFixed(prec * 2))).toFixed(prec * 2)) / k;
    };
  s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
  var re = /(-?\d+)(\d{3})/;
  while (re.test(s[0])) {
    s[0] = s[0].replace(re, "$1" + sep + "$2");
  }

  if ((s[1] || '').length < prec) {
    s[1] = s[1] || '';
    s[1] += new Array(prec - s[1].length + 1).join('0');
  }
  return s.join(dec);
}
